
<style>
    .vue-file-uploader {
        position: relative;
        overflow: hidden;
        background: white;
        padding: 10px;
    }

    .vue-file-uploader * {
        padding: 0;
        margin: 0;
        font-family: "microsoft yahei"
    }

    .vue-file-uploader .controls-box{
        position: relative;
        width: 320px;
        float: left;
        overflow: hidden;
    }

    .vue-file-uploader .file-input{
        position: relative;
        float: left;
    }
    .vue-file-uploader .button{
        position: relative;
        display: block;
        text-align: center;
        text-decoration: none;
        width: 240px;
        cursor: pointer;
        line-height: 28px;
        font-weight: normal;
        border: none;
        background: #2a87d8;
        color: #FFF;
        font-size: 12px;
    }
    .vue-file-uploader .button.rechoose{
        background-color: #0da952;
    }
    .vue-file-uploader .button.reupload{
        background-color: #d66422;
    }
    .vue-file-uploader .button.choose{
        background-color: #186be8;
    }

    .vue-file-uploader .file-input input{
        opacity: 0;
        position: absolute;
        top: 0;
        left: 0;
    }

    .vue-file-uploader .upload-control{
        position: relative;
        float: right;
    }
    .vue-file-uploader .upload-control button{
        width: 64px;
        line-height: 28px;
        border: none;
        background: #2183e8;
        color: white;
        cursor: pointer;
        font-size: 14px;
        font-weight: normal;
    }
    .vue-file-uploader .upload-control button[disabled]{
        opacity: 0.6;
    }
    .vue-file-uploader .preview{
        position: relative;
        text-align: center;
        width: 100%;
        float: left;
    }
    .vue-file-uploader .preview a{}
    .vue-file-uploader .preview a img{
        max-width: 100%;
    }
    .vue-file-uploader .preview video{
        max-width: 100%;
    }

    .vue-file-uploader .upload-progress{
        position: relative;
        text-align: center;
        width: 100%;
        height: 24px;
        float: left;
        margin: 10px 0 5px;
    }
    .vue-file-uploader .upload-progress progress{
        width: 100%;
    }

    .vue-file-uploader .tips{
        position: relative;
        text-align: center;
        width: 100%;
        height: 24px;
        float: left;
    }
    .vue-file-uploader .tips span{}
</style>

<script type="text/x-template" id="uploader-template">
    <div class="vue-file-uploader">
        <div class="controls-box">
            <label class="file-input">
                <a class="button rechoose" v-show="file">已选择，点击重新选择文件</a>
                <a class="button reupload" v-show="!file && value">已上传，点击重新上传文件</a>
                <a class="button choose" v-show="!file && !value">点击请选择文件</a>
                <input type="file" @change="change" :accept="accept">
            </label>
            <div class="upload-progress"><progress :value="progress"></progress></div>
            <div class="preview" v-if="value">
                <a v-if="isImage" :href="fullUrl" target="_blank"><img :src="fullUrl+'?x-oss-process=image/resize,h_120'"></a>
                <video v-if="isVideo" :src="fullUrl" controls></video>
                <a v-if="isAudio" :href="fullUrl" target="_blank">{{getFileName(fullUrl)}}</a>
                <audio v-if="isAudio" :src="fullUrl" controls></audio>
            </div>
            <div class="tips" v-show="tips.text" ><span :style="{color:tips.color}">{{tips.text}}</span></div>
            <div style="display:none!important;">
                <img v-if="isImage" ref="preview">
                <video v-if="isVideo" controls ref="preview"></video>
                <audio v-if="isAudio" controls ref="preview"></audio>
            </div>
        </div>
    </div>
</script>

<script>
Vue.component('file-uploader', {
    template: '#uploader-template',
    props: {
        value: {
            type: [String],
            default: ''
        },
        uploadurl: {
            type: [String],
            default: ''
        },
        urlprefix: {
            type: [String],
            default: ''
        },
        placeholder: {
            type: String,
            default: ''
        },
        filename: {
            type: [String],
            default: ''
        },
        params: {
            type: [Object],
            default: function () {
                return {}
            }
        },
        filetype: {
            type: [String],
            default: 'image'
        },
        catalogue: {
            type: [String],
            default: ''
        },
        filesize: {
            type: [Number,String],
            default: '512k'
        },
        oss: {
            default: true
        },
        policyurl: {
            type: String,
            default: '',
            require: true
        },
        options: {
            type: [Object],
            default: function () {
                return {
                    video: {
                        width: 240,
                        height: 160
                    },
                    image: {
                        width: 200,
                        height: 150
                    }
                };
            }
        }
    },
    data: function () {

        var useOss = false;
        if (typeof this.oss == "string") {
            useOss = ("true" == this.oss);
        } else if (typeof this.oss == "number") {
            useOss = (1 == this.oss);
        } else if (this.oss instanceof Boolean) {
            useOss = this.oss;
        }

        var ossClient = null;
        if (this.useOss) {
            ossClient = new AliyunOssUploader();
        }

        if (this.filesize) {
            var fs = this.filesize;
            var _ext = fs.substring(fs.length-1);
            var _num = fs.substring(0, fs.length-1);
            var maxFileSize = parseInt(_num);
            if (_ext == 'k' || _ext == 'K') {
                maxFileSize = parseInt(1024 * _num);
            } else if (_ext == 'm' || _ext == 'M') {
                maxFileSize = parseInt(1024 * 1024 * _num);
            }
        } else {
            maxFileSize = 1024 * 1024;
        }


        return {
            file: null,
            fileInput: null,
            progress: 0,
            FileTypes: {
                image: 'image/jpeg, image/png, image/gif',
                video: 'video/mp4',
                audio: 'audio/mpeg',
                apk: ''
            },
            tips: {
                text: null,
                color: 'white'
            },
            prefix: '',
            useOss: useOss,
            ossClient: ossClient,
            result: null,
            maxFileSize: maxFileSize
        }
    },
    created: function () {
        if (this.useOss && !this.policyurl) {
            throw new DOMException('policyurl无效');
        }
        if (undefined === this.FileTypes[this.filetype]) throw new DOMException('文件类型不支持');
        this.prefix = this.urlprefix ? (this.urlprefix[this.urlprefix.length - 1] == '/' ? this.urlprefix : this.urlprefix + '/') : '';
    },
    computed: {
        accept: function () {
            return this.FileTypes[this.filetype];
        },
        isImage: function () {
            return 'image' == this.filetype;
        },
        isVideo: function () {
            return 'video' == this.filetype;
        },
        isAudio: function () {
            return 'audio' == this.filetype;
        },
        uploadDisabled: function () {
            return !(this.file instanceof File);
        },
        fullUrl: function () {
            return this.prefix + this.value;
        }
    },
    methods: {
        change: function (input) {

            this.fileInput = input.target;
            var file = this.fileInput.files[0];
            if (file.size > this.maxFileSize) {
                alert("文件大小不能超过"+this.filesize);
                this.fileInput.value = null;
                return;
            }

            this.setDuration(URL.createObjectURL(file));

            this.file = file;
            this.setProgress(0);
            this.upload();
        },
        setValue: function (val) {
            this.result = val;
            this.$emit('input', val);
        },
        setDuration: function (url) {
            var this$1 = this;
            if ('video' == this.filetype || 'audio' == this.filetype) {
                this.$refs.preview.src = url;
                this.$refs.preview.ondurationchange = function () {
                    console.log(this.duration)
                    if (this.duration && this.duration > 0)
                        this$1.$emit('duration', this.duration);
                };
            }
        },
        clearFile: function () {
            this.fileInput.value = '';
            this.file = null;
        },
        setProgress: function (val) {
            this.progress = val;
        },
        upload: function () {

            if (this.file == null) {
                this.tips = {text: '请选择文件', color: 'red'};
                return;
            }
            this.tips = {text: null, color: 'white'};

            if (this.useOss) {
                this.uploadOSS();
            } else {
            }
        },
        uploadOSS: function () {

            var success = function (resp) {
                if (200 != resp.code) throw new DOMException(resp);

                var data = resp.data;

                var t = Date.now(), name = this.file.name;
                var path = data.dir + "/" + t + randomString() + name.substr(name.lastIndexOf('.'));

                var formData = new FormData();
                formData.append('policy', data.policy);
                formData.append('OSSAccessKeyId', data.accessid);
                formData.append('success_action_status', 200);
                formData.append('signature', data.signature);
                formData.append('key', path);
                formData.append('file', this.file);

                this.$http.post(data.host, formData, {progress: this.uploadProgress}).then(function (resp) {
                    this.setValue((data.dns || data.host) + '/' + path);
                    this.clearFile();
                });

//                $.ajax({
//                    url: data.host,
//                    data: formData,
//                    success: function () {
//                        this.setValue(data.host + '/' + path);
//                        this.clearFile();
//                    }.bind(this),
//                    xhr: function(){
//                        var xhr = $.ajaxSettings.xhr();
//                        if(this.uploadProgress && xhr.upload) {
//                            xhr.upload.addEventListener("progress" , this.uploadProgress, false);
//                            return xhr;
//                        }
//                    }.bind(this)
//                });

            }.bind(this);

            ajax({
                uri: this.policyurl,
                data: {type: this.filetype, maxsize: this.maxFileSize},
                success: success
            });

        },
        uploadProgress: function (e) {
            this.setProgress(e.loaded / e.total);
        },
        getFileName: function (uri) {
            return uri ? uri.substr(uri.lastIndexOf('/')+1) : uri;
        }
    },
    watch: {
        value: function (nv, ov) {
            if (nv) {
                this.setDuration(nv);
            }
            this.file = null;
        }
    }
});
</script>
